

using System;
using System.Collections.Generic;
using System.Text;

using System.Collections.Specialized;
using JTC.MiniCommerce.Core;
using JTC.MiniCommerce.Core.Serialization;
using JTC.MiniCommerce.Localization;

namespace JTC.MiniCommerce.Store {

  public partial class Order {
  
    #region Member Variables

    private OrderItemCollection _orderItemCollection;
    private Address _billingAddress;
    private Address _shippingAddress;
    private TransactionCollection _transactionCollection;
    private ExtendedProperties _extendedProperties;
    
    
    #endregion
    
    #region Properties

    /// <summary>
    /// Gets the order item collection.
    /// </summary>
    /// <value>The order item collection.</value>
    public OrderItemCollection OrderItemCollection {
      get {
        if(_orderItemCollection == null) {
          _orderItemCollection = this.OrderItemRecords();
        }
        return _orderItemCollection;
      }
    }

    /// <summary>
    /// Gets the transaction collection.
    /// </summary>
    /// <value>The transaction collection.</value>
    public TransactionCollection TransactionCollection {
      get {
        if(_transactionCollection == null) {
          _transactionCollection = this.TransactionRecords();
        }
        return _transactionCollection;
      }
    }

    /// <summary>
    /// Gets the sub total.
    /// </summary>
    /// <value>The sub total.</value>
    public decimal SubTotal {
      get {
        decimal _subTotal = 0;
        foreach(OrderItem orderItem in this.OrderItemCollection) {
          _subTotal += (orderItem.PricePaid * orderItem.Quantity);
        }
        return _subTotal;
      }
    }

    /// <summary>
    /// Gets the tax total.
    /// </summary>
    /// <value>The tax total.</value>
    public decimal TaxTotal {
      get {
        decimal _taxTotal = 0;
        foreach(OrderItem orderItem in this.OrderItemCollection) {
          _taxTotal += orderItem.ItemTax;
        }
        return _taxTotal;
      }
    }

    /// <summary>
    /// Gets the total.
    /// </summary>
    /// <value>The total.</value>
    public decimal Total {
      get {
        return this.SubTotal + this.ShippingAmount + this.TaxAmount + this.HandlingAmount - this.DiscountAmount;
      }
    }

    /// <summary>
    /// Gets the total weight.
    /// </summary>
    /// <value>The total weight.</value>
    public decimal TotalWeight {
      get {
        decimal _totalWeight = 0;
        foreach(OrderItem item in this.OrderItemCollection) {
          _totalWeight += (item.Weight * item.Quantity);
        }
        return _totalWeight;
      }
    }

    /// <summary>
    /// Gets the shipping address.
    /// </summary>
    /// <value>The shipping address.</value>
    public Address ShippingAddress {
      get {
        if(!string.IsNullOrEmpty(this.ShipToAddress)) {
          _shippingAddress = new Address().NewFromXml(this.ShipToAddress) as Address;
        }
        return _shippingAddress;
      }
    }

    /// <summary>
    /// Gets the billing address.
    /// </summary>
    /// <value>The billing address.</value>
    public Address BillingAddress {
      get {
        if(_billingAddress == null) {
          if(!string.IsNullOrEmpty(this.BillToAddress)) {
            _billingAddress = new Address().NewFromXml(this.BillToAddress) as Address;
          }
        }
        return _billingAddress;
      }
    }

    /// <summary>
    /// Gets the extended properties.
    /// </summary>
    /// <value>The extended properties.</value>
    public ExtendedProperties ExtendedProperties {
      get {
        if(_extendedProperties == null) {
          if(!string.IsNullOrEmpty(this.AdditionalProperties)) {
            _extendedProperties = new ExtendedProperties().NewFromXml(this.AdditionalProperties) as ExtendedProperties;
          }
          else {
            _extendedProperties = new ExtendedProperties();
          }
        }
        return _extendedProperties;
      }
    }
	
	  #endregion

    #region "Credit Card Information"

    [NonSerialized(), System.Xml.Serialization.XmlIgnore()]
    private string _creditCardNumber;
    [NonSerialized(), System.Xml.Serialization.XmlIgnore()]
    private int _crediCardExpirationYear;
    [NonSerialized(), System.Xml.Serialization.XmlIgnore()]
    private int _creditCardExpirationMonth;
    [NonSerialized(), System.Xml.Serialization.XmlIgnore()]
    private string _creditCardSecurityNumber;
    [NonSerialized(), System.Xml.Serialization.XmlIgnore()]
    private CreditCardType _creditCardType;

    /// <summary>
    /// Gets or sets the credit card number.
    /// </summary>
    /// <value>The credit card number.</value>
    [System.Xml.Serialization.XmlIgnore()]
    public string CreditCardNumber {
      get {
        return _creditCardNumber;
      }
      set {
        _creditCardNumber = value;
      }
    }

    /// <summary>
    /// Gets or sets the credit card expiration year.
    /// </summary>
    /// <value>The credit card expiration year.</value>
    [System.Xml.Serialization.XmlIgnore()]
    public int CreditCardExpirationYear {
      get {
        return _crediCardExpirationYear;
      }
      set {
        _crediCardExpirationYear = value;
      }
    }

    /// <summary>
    /// Gets or sets the credit card expiration month.
    /// </summary>
    /// <value>The credit card expiration month.</value>
    [System.Xml.Serialization.XmlIgnore()]
    public int CreditCardExpirationMonth {
      get {
        return _creditCardExpirationMonth;
      }
      set {
        _creditCardExpirationMonth = value;
      }
    }

    /// <summary>
    /// Gets or sets the credit card security number.
    /// </summary>
    /// <value>The credit card security number.</value>
    [System.Xml.Serialization.XmlIgnore()]
    public string CreditCardSecurityNumber {
      get {
        return _creditCardSecurityNumber;
      }
      set {
        _creditCardSecurityNumber = value;
      }
    }


    /// <summary>
    /// Gets or sets the type of the credit card.
    /// </summary>
    /// <value>The type of the credit card.</value>
    [System.Xml.Serialization.XmlIgnore()]
    public CreditCardType CreditCardType {
      get {
        return _creditCardType;
      }
      set {
        _creditCardType = value;
      }
    }


    #endregion

    #region String Methods

    /// <summary>
    /// To HTML.
    /// </summary>
    /// <returns></returns>
    public string ToHtml() {
      StringBuilder sb = new StringBuilder();
      sb.Append("<table class=\"receiptTable\">");
      sb.Append(string.Format("<tr><td colspan=\"2\">{0}&nbsp;{1}</td></tr>", LocalizationUtility.GetStoreString("OrderNumber"), this.OrderNumber));
      sb.Append(string.Format("<tr><td colspan=\"2\">{0}&nbsp:{1}</td></tr>", LocalizationUtility.GetStoreString("OrderStatus"), CoreUtility.ParseCamelToProper(Enum.GetName(typeof(OrderStatus), (int)this.OrderStatusId))));
      if(this.TransactionCollection.Count > 0) {
        sb.Append(string.Format("<tr><td colspan=\"2\">{0}&nbsp;{1}&nbsp;{2}</td></tr>", LocalizationUtility.GetStoreString("OrderDate"), this.TransactionCollection[0].TransactionDate.ToLongDateString(), this.TransactionCollection[0].TransactionDate.ToLongTimeString()));
        sb.Append("<tr><td colspan=\"2\">&nbsp;</td></tr>");
        sb.Append(string.Format("<tr><td colspan=\"2\">{0}</td></tr>", LocalizationUtility.GetStoreString("PaymentInformation")));
        sb.Append(string.Format("<tr><td colspan=\"2\">{0}&nbsp;{1}</td></tr>", LocalizationUtility.GetStoreString("PaymentMethod"), this.TransactionCollection[0].PaymentMethod));
        sb.Append(string.Format("<tr><td colspan=\"2\">{0}&nbsp;{1}</td></tr>", LocalizationUtility.GetStoreString("TransactionCode"), this.TransactionCollection[0].GatewayTransactionId));
      }
      sb.Append(string.Format("<tr><td colspan=\"2\">{0}</td></tr>", LocalizationUtility.GetStoreString("ShippingAndBilling")));
      sb.Append("<tr><td colspan=\"2\">&nbsp;</td></tr>");
      sb.Append(string.Format("<tr><td valign=\"top\">{0}<br>{1}</td><td valign=\"top\">{2}<br>{3}<br><br><br><br></td></tr>", LocalizationUtility.GetStoreString("BillTo"), this.BillingAddress != null ? this.BillingAddress.ToHtmlString() : string.Empty, LocalizationUtility.GetStoreString("ShipTo"), this.ShippingAddress.ToHtmlString()));
      sb.Append(string.Format("<tr><td colspan=\"2\">{0}</td></tr>", LocalizationUtility.GetStoreString("OrderItems")));
      sb.Append("<tr><td colspan=\"2\">&nbsp;</td></tr>");
      sb.Append(string.Format("<tr><td colspan=\"2\">{0}</td></tr>", this.ItemsToString()));
      sb.Append("</table>");

      return sb.ToString();

    }

    /// <summary>
    /// Items to string.
    /// </summary>
    /// <returns></returns>
    public string ItemsToString() {

      StringBuilder sb = new StringBuilder();
      sb.Append("<table class=\"receiptTable\">");
      sb.Append(string.Format("<tr><th>{0}</th><th>{1}</th><th>{2}</th><th>{3}</th><th>{4}</th></tr>", LocalizationUtility.GetStoreString("hdrItemNumber"), LocalizationUtility.GetStoreString("hdrItemName"), LocalizationUtility.GetStoreString("hdrQuantity"), LocalizationUtility.GetStoreString("hdrPrice"), LocalizationUtility.GetStoreString("hdrExtendedPrice")));

      string appendFormat = "<tr><td class=\"itemSku\">{0}</td><td class=\"itemName\">{1}</td><td class=\"itemQuantity\" align=\"right\">{2}</td><td class=\"itemAmount\" align=\"right\">{3}</td><td class=\"itemAmount\" align=\"right\">{4}</td></tr>";
      string appendAltFormat = "<tr><td class=\"itemSku\">{0}</td><td class=\"itemName\">{1}</td><td class=\"itemQuantity\" align=\"right\">{2}</td><td class=\"itemAmount\" align=\"right\">{3}</td><td class=\"itemAmount\" align=\"right\">{4}</td></tr>";
      string formatToUse = appendFormat;

      bool isEven = true;

      foreach(OrderItem item in this.OrderItemCollection) {

        if(isEven) {
          formatToUse = appendFormat;
        }
        else {
          formatToUse = appendAltFormat;
        }
        string attSelections = "";
        if(item.Attributes != string.Empty) {
          attSelections = "<br>" + item.Attributes;
        }

        sb.AppendFormat(formatToUse, item.Sku, item.Name + " " + attSelections, item.Quantity.ToString(), StoreUtility.GetFormattedAmount(item.PricePaid, true), StoreUtility.GetFormattedAmount(item.ExtendedPrice, true));
        isEven = !isEven;
      }

      sb.Append(string.Format("<tr><td colspan=\"4\" class=\"subTotal\" align=\"right\">{0}</td><td class=\"subTotalAmount\" align=\"right\">{1}</td></tr>", LocalizationUtility.GetStoreString("Subtotal"), StoreUtility.GetFormattedAmount(this.SubTotal, true)));
      sb.Append(string.Format("<tr><td colspan=\"4\" class=\"subTotal\" align=\"right\">{0}</td><td class=\"subTotalAmount\" align=\"right\">{1}</td></tr>", LocalizationUtility.GetStoreString("Tax"), StoreUtility.GetFormattedAmount(this.TaxAmount, true)));
      sb.Append(string.Format("<tr><td colspan=\"4\" class=\"subTotal\" align=\"right\">{0}</td><td class=\"subTotalAmount\" align=\"right\">{1}</td></tr>", LocalizationUtility.GetStoreString("ShippingAndHandling"), StoreUtility.GetFormattedAmount(this.ShippingAmount, true)));
      if(this.DiscountAmount > 0) {
        sb.Append(string.Format("<tr><td colspan=\"4\" class=\"subTotal\" align=\"right\">{0}</td><td class=\"subTotalAmount\" align=\"right\">- {1}</td></tr>", LocalizationUtility.GetStoreString("Coupon"), StoreUtility.GetFormattedAmount(this.DiscountAmount, true)));
      }
      else {
        sb.Append(string.Format("<tr><td colspan=\"4\" class=\"subTotal\" align=\"right\">{0}</td><td class=\"subTotalAmount\" align=\"right\">{1}</td></tr>", LocalizationUtility.GetStoreString("Coupon"), StoreUtility.GetFormattedAmount(this.DiscountAmount, true)));
      }
      sb.Append(string.Format("<tr><td colspan=\"4\" class=\"total\" align=\"right\">{0}</td><td class=\"totalAmount\" align=\"right\">{1}</td></tr>", LocalizationUtility.GetStoreString("Total"), StoreUtility.GetFormattedAmount(this.Total, true)));

      sb.Append("</table>");
      return sb.ToString();
    }


    #endregion

  }
}
